home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Magazin: Amiga-CD 1997 September & October
/
Amiga-CD 1997 #9-10.iso
/
aminet
/
gameboyemulator
/
debug.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-10-29
|
11KB
|
220 lines
/** VGB: portable GameBoy emulator ***************************/
/** **/
/** Debug.c **/
/** **/
/** This file contains the built-in debugging routine for **/
/** the GameBoy emulator which is called on each CPU step **/
/** when Trap==TRUE. **/
/** **/
/** Copyright (C) Marat Fayzullin 1995 **/
/** You are not allowed to distribute this software **/
/** commercially. Please, notify me, if you make any **/
/** changes to this file. **/
/*************************************************************/
#include <stdio.h>
#include <string.h>
#include "Z80.h"
void HexByte(char *S,byte V);
int DAsm(char *S,byte *A);
char *Mnemonics[256] =
{
"NOP","LD BC,$#","LD (BC),A","INC BC","INC B","DEC B","LD B,$*","RLCA",
"LD ($#),SP","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,$*","RRCA",
"STOP","LD DE,$#","LD (DE),A","INC DE","INC D","DEC D","LD D,$*","RLA",
"JR $@","ADD HL,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,$*","RRA",
"JR NZ,$@","LD HL,$#","LD (HL+),A","INC HL","INC H","DEC H","LD H,$*","DAA",
"JR Z,$@","ADD HL,HL","LD A,(HL+)","DEC HL","INC L","DEC L","LD L,$*","CPL",
"JR NC,$@","LD SP,$#","LD (HL-),A","INC SP","INC (HL)","DEC (HL)","LD (HL),$*","SCF",
"JR C,$@","ADD HL,SP","LD A,(HL-)","DEC SP","INC A","DEC A","LD A,$*","CCF",
"LD B,B","LD B,C","LD B,D","LD B,E","LD B,H","LD B,L","LD B,(HL)","LD B,A",
"LD C,B","LD C,C","LD C,D","LD C,E","LD C,H","LD C,L","LD C,(HL)","LD C,A",
"LD D,B","LD D,C","LD D,D","LD D,E","LD D,H","LD D,L","LD D,(HL)","LD D,A",
"LD E,B","LD E,C","LD E,D","LD E,E","LD E,H","LD E,L","LD E,(HL)","LD E,A",
"LD H,B","LD H,C","LD H,D","LD H,E","LD H,H","LD H,L","LD H,(HL)","LD H,A",
"LD L,B","LD L,C","LD L,D","LD L,E","LD L,H","LD L,L","LD L,(HL)","LD L,A",
"LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E","LD (HL),H","LD (HL),L","HALT","LD (HL),A",
"LD A,B","LD A,C","LD A,D","LD A,E","LD A,H","LD A,L","LD A,(HL)","LD A,A",
"ADD B","ADD C","ADD D","ADD E","ADD H","ADD L","ADD (HL)","ADD A",
"ADC B","ADC C","ADC D","ADC E","ADC H","ADC L","ADC (HL)","ADC A",
"SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A",
"SBC B","SBC C","SBC D","SBC E","SBC H","SBC L","SBC (HL)","SBC A",
"AND B","AND C","AND D","AND E","AND H","AND L","AND (HL)","AND A",
"XOR B","XOR C","XOR D","XOR E","XOR H","XOR L","XOR (HL)","XOR A",
"OR B","OR C","OR D","OR E","OR H","OR L","OR (HL)","OR A",
"CP B","CP C","CP D","CP E","CP H","CP L","CP (HL)","CP A",
"RET NZ","POP BC","JP NZ,$#","JP $#","CALL NZ,$#","PUSH BC","ADD $*","RST 00h",
"RET Z","RET","JP Z,$#","PREFIX CBh","CALL Z,$#","CALL $#","ADC $*","RST 08h",
"RET NC","POP DE","JP NC,$#","DB D3h","CALL NC,$#","PUSH DE","SUB $*","RST 10h",
"RET C","RETI","JP C,$#","DB DBh","CALL C,$#","DB DDh","SBC $*","RST 18h",
"LD ($FF*),A","POP HL","LD (FF00h+C),A","EX HL,(SP)","DB E4h","PUSH HL","AND $*","RST 20h",
"ADD SP,$@","LD PC,HL","LD ($#),A","DB EBh","DB ECh","PREFIX EDh","XOR $*","RST 28h",
"LD A,($FF*)","POP AF","DB F2h","DI","DB F4h","PUSH AF","OR $*","RST 30h",
"LDHL SP,$@","LD SP,HL","LD A,($#)","EI","DB FCh","DB FDh","CP $*","RST 38h"
};
char *MnemonicsCB[256] =
{
"RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (HL)","RLC A",
"RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (HL)","RRC A",
"RL B","RL C","RL D","RL E","RL H","RL L","RL (HL)","RL A",
"RR B","RR C","RR D","RR E","RR H","RR L","RR (HL)","RR A",
"SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (HL)","SLA A",
"SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (HL)","SRA A",
"SWAP B","SWAP C","SWAP D","SWAP E","SWAP H","SWAP L","SWAP (HL)","SWAP A",
"SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (HL)","SRL A",
"BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(HL)","BIT 0,A",
"BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(HL)","BIT 1,A",
"BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(HL)","BIT 2,A",
"BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(HL)","BIT 3,A",
"BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(HL)","BIT 4,A",
"BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(HL)","BIT 5,A",
"BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(HL)","BIT 6,A",
"BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(HL)","BIT 7,A",
"RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(HL)","RES 0,A",
"RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(HL)","RES 1,A",
"RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(HL)","RES 2,A",
"RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(HL)","RES 3,A",
"RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(HL)","RES 4,A",
"RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(HL)","RES 5,A",
"RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(HL)","RES 6,A",
"RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(HL)","RES 7,A",
"SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(HL)","SET 0,A",
"SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(HL)","SET 1,A",
"SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(HL)","SET 2,A",
"SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(HL)","SET 3,A",
"SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(HL)","SET 4,A",
"SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(HL)","SET 5,A",
"SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(HL)","SET 6,A",
"SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(HL)","SET 7,A"
};
char *MnemonicsED[256] =
{
"FUCK00","FUCK01","FUCK02","FUCK03","FUCK04","FUCK05","FUCK06","FUCK07",
"FUCK08","FUCK09","FUCK0A","FUCK0B","FUCK0C","FUCK0D","FUCK0E","FUCK0F",
"FUCK10","FUCK11","FUCK12","FUCK13","FUCK14","FUCK15","FUCK16","FUCK17",
"FUCK18","FUCK19","FUCK1A","FUCK1B","FUCK1C","FUCK1D","FUCK1E","FUCK1F",
"FUCK20","FUCK21","FUCK22","FUCK23","FUCK24","FUCK25","FUCK26","FUCK27",
"FUCK28","FUCK29","FUCK2A","FUCK2B","FUCK2C","FUCK2D","FUCK2E","FUCK2F",
"FUCK30","FUCK31","FUCK32","FUCK33","FUCK34","FUCK35","FUCK36","FUCK37",
"FUCK38","FUCK39","FUCK3A","FUCK3B","FUCK3C","FUCK3D","FUCK3E","FUCK3F",
"FUCK40","FUCK41","SBC HL,BC","LD ($#),BC","FUCK44","RETN","IM 0","LD I,A",
"FUCK48","FUCK49","ADC HL,BC","LD BC,($#)","FUCK4C","RETI","FUCK4E","LD R,A",
"FUCK50","FUCK51","SBC HL,DE","LD ($#),DE","FUCK54","FUCK55","IM 1","LD A,I",
"FUCK58","FUCK59","ADC HL,DE","LD DE,($#)","FUCK5C","FUCK5D","IM 2","LD A,R",
"FUCK60","FUCK61","SBC HL,HL","LD ($#),HL","FUCK64","FUCK65","FUCK66","RRD",
"FUCK68","FUCK69","ADC HL,HL","LD HL,($#)","FUCK6C","FUCK6D","FUCK6E","RLD",
"FUCK70","FUCK71","SBC HL,SP","LD ($#),SP","FUCK74","FUCK75","FUCK76","FUCK77",
"FUCK78","FUCK79","ADC HL,SP","LD SP,($#)","FUCK7C","FUCK7D","FUCK7E","FUCK7F",
"FUCK80","FUCK81","FUCK82","FUCK83","FUCK84","FUCK85","FUCK86","FUCK87",
"FUCK88","FUCK89","FUCK8A","FUCK8B","FUCK8C","FUCK8D","FUCK8E","FUCK8F",
"FUCK90","FUCK91","FUCK92","FUCK93","FUCK94","FUCK95","FUCK96","FUCK97",
"FUCK98","FUCK99","FUCK9A","FUCK9B","FUCK9C","FUCK9D","FUCK9E","FUCK9F",
"LDI","CPI","FUCKA2","FUCKA3","FUCKA4","FUCKA5","FUCKA6","FUCKA7",
"LDD","CPD","FUCKAA","FUCKAB","FUCKAC","FUCKAD","FUCKAE","FUCKAF",
"LDIR","CPIR","FUCKB2","FUCKB3","FUCKB4","FUCKB5","FUCKB6","FUCKB7",
"LDDR","CPDR","FUCKBA","FUCKBB","FUCKBC","FUCKBD","FUCKBE","FUCKBF",
"FUCKC0","FUCKC1","FUCKC2","FUCKC3","FUCKC4","FUCKC5","FUCKC6","FUCKC7",
"FUCKC8","FUCKC9","FUCKCA","FUCKCB","FUCKCC","FUCKCD","FUCKCE","FUCKCF",
"FUCKD0","FUCKD1","FUCKD2","FUCKD3","FUCKD4","FUCKD5","FUCKD6","FUCKD7",
"FUCKD8","FUCKD9","FUCKDA","FUCKDB","FUCKDC","FUCKDD","FUCKDE","FUCKDF",
"FUCKE0","FUCKE1","FUCKE2","FUCKE3","FUCKE4","FUCKE5","FUCKE6","FUCKE7",
"FUCKE8","FUCKE9","FUCKEA","FUCKEB","FUCKEC","FUCKED","FUCKEE","FUCKEF",
"FUCKF0","FUCKF1","FUCKF2","FUCKF3","FUCKF4","FUCKF5","FUCKF6","FUCKF7",
"FUCKF8","FUCKF9","FUCKFA","FUCKFB","FUCKFC","FUCKFD","FUCKFE","FUCKFF"
};
void HexByte(char *S,byte V)
{
static char Digits[]="0123456789ABCDEF";
*S++=Digits[V>>4];*S++=Digits[V&0x0F];*S='\0';
}
int DAsm(char *S,byte *A)
{
char H[3],*T,*P;
byte *B,J;
B=A;
switch(*B)
{
case 0xCB: B++;T=MnemonicsCB[*B++];break;
case 0xED: B++;T=MnemonicsED[*B++];break;
default: T=Mnemonics[*B++];
}
if(P=strchr(T,'*'))
{
strncpy(S,T,P-T);S[P-T]='\0';
HexByte(H,*B++);strcat(S,H);
strcat(S,P+1);
}
else
if(P=strchr(T,'@'))
{
strncpy(S,T,P-T);S[P-T]='\0';
strcat(S,*B&0x80? "-":"+");
J=*B&0x80? 256-*B:*B;B++;
HexByte(H,J);strcat(S,H);
strcat(S,P+1);
}
else
if(P=strchr(T,'#'))
{
strncpy(S,T,P-T);S[P-T]='\0';
HexByte(H,*(++B));strcat(S,H);
HexByte(H,*(B-1));strcat(S,H);
B++;strcat(S,P+1);
}
else strcpy(S,T);
return(B-A);
}
/*** Single-step debugger ****************************/
/*** This function should exist if DEBUG is ***/
/*** #defined. When Trace=TRUE, it is called after ***/
/*** each command executed by the CPU and given ***/
/*** address of the address space and the register ***/
/*** file. ***/
/*****************************************************/
void Z80_Debug(byte *A,reg R)
{
char S[128];
extern byte Trace;
extern word Trap;
extern word OldTrap;
int ch;
DAsm(S,A+R.PC.W);
printf
(
"AF:%hX HL:%hX DE:%hX BC:%hX PC:%hX SP:%hX IX:%hX IY:%hX \n",
R.AF.W,R.HL.W,R.DE.W,R.BC.W,R.PC.W,R.SP.W,R.IX.W,R.IY.W
);
printf
(
"AT PC: [%hX - %s] AT SP: [%X]\n\n",
*(A+R.PC.W),S,*(A+R.SP.W)+((word)*(A+R.SP.W+1)<<8)
);
printf("Next command (Y/n/r) ? ");
ch=getchar();
if (ch == 'n') { Trace=!Trace; Trap=OldTrap; }
if (ch == 'r')
{
printf("Run until adress $");
scanf("%hx",&Trap);
Trace=!Trace;
}
printf("\n");
fflush(stdout);
}